package com.ht.web_vr_home_tour_backend.controller;

import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ht.web_vr_home_tour_backend.obj.dto.ResData;
import com.ht.web_vr_home_tour_backend.obj.dto.UserInfoDto;
import com.ht.web_vr_home_tour_backend.obj.enums.ObjType;
import com.ht.web_vr_home_tour_backend.obj.enums.UserLevel;
import com.ht.web_vr_home_tour_backend.obj.pojo.ObjInfo;
import com.ht.web_vr_home_tour_backend.obj.vo.ObjInfoVo;
import com.ht.web_vr_home_tour_backend.service.ObjInfoService;
import com.ht.web_vr_home_tour_backend.utils.ThreadLocalUtil;
import com.ht.web_vr_home_tour_backend.utils.exceptions.MessageException;
import com.ht.web_vr_home_tour_backend.utils.interfaces.RequiredUserLevel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

@Api(tags = "对象数据控制器")
@RestController
@RequestMapping("/api/obj")
public class ObjInfoController {

    private static final Logger log = LoggerFactory.getLogger(ObjInfoController.class);
    private final ObjInfoService objInfoService;

    public ObjInfoController(ObjInfoService objInfoService) {
        this.objInfoService = objInfoService;
    }

    @GetMapping("/info/{id}")
    @ApiOperation("根据id获取对象信息")
    @RequiredUserLevel(UserLevel.User)
    public ResData<ObjInfoVo> getObjInfo(@PathVariable("id") Long id) {
        ObjInfo objInfo = objInfoService.getObjInfoById(id);
        return ResData.success(new ObjInfoVo(objInfo));
    }

    @GetMapping("/{link}")
    @ApiOperation("通过图片link获取对象")
    @RequiredUserLevel(UserLevel.Tourists)
    public void getImageByLink(@PathVariable("link") String link, HttpServletResponse response) {
        try (
                ServletOutputStream os = response.getOutputStream();
                InputStream is = objInfoService.getObjByLink(link)
        ) {
            IoUtil.copy(is, os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/page")
    @ApiOperation("分页查询当前用户上传的对象文件")
    @RequiredUserLevel(UserLevel.User)
    public ResData<Page<ObjInfoVo>> pageObjInfo(
            @RequestParam(value = "current", defaultValue = "1") Long current,
            @RequestParam(value = "size", defaultValue = "10") Long size,
            @RequestParam(value = "type", defaultValue = "null") String type
    ) {
        UserInfoDto userInfoDto = ThreadLocalUtil.getUserInfoDto();
        if (userInfoDto == null || userInfoDto.getId() == null) {
            throw new RuntimeException("无法读到用户信息");
        }
        return ResData.success(objInfoService.pageObj(current, size, type, userInfoDto.getId()));
    }

    @GetMapping("/page/all")
    @ApiOperation("分页查询所有对象文件")
    @RequiredUserLevel(UserLevel.Admin)
    public ResData<Page<ObjInfoVo>> pageAllObjInfo (
            @RequestParam(value = "current", defaultValue = "1") Long current,
            @RequestParam(value = "size", defaultValue = "10") Long size,
            @RequestParam(value = "type", defaultValue = "") String type
    ) {
        return ResData.success(objInfoService.pageObj(current, size, type, null));
    }

    @PostMapping
    @ApiOperation("上传对象")
    @RequiredUserLevel(UserLevel.User)
    public ResData<ObjInfoVo> uploadObj(
            @RequestHeader("type") String type,
            @RequestParam("file") MultipartFile file
    ) {
        try {
            ObjType objType = ObjType.valueOf(type);
            ObjInfo objInfo = objInfoService.uploadObj(objType, file);
            return ResData.success(new ObjInfoVo(objInfo));
        } catch (IllegalArgumentException e) {
            throw new MessageException("无法识别文件类型，请更换文件重试");
        }
    }

    @GetMapping("/delete/{objId}")
    @ApiOperation("根据id删除对象")
    @RequiredUserLevel(UserLevel.User)
    public ResData<Void> deleteObj(@PathVariable String objId) {
        objInfoService.deleteObj(Long.parseLong(objId));
        return ResData.success();
    }

    @PostMapping("/update")
    @ApiOperation("更新对象")
    @RequiredUserLevel(UserLevel.User)
    public ResData<Void> updateObj(@RequestBody ObjInfo objInfo) {
        objInfoService.updateObjInfo(objInfo);
        return ResData.success();
    }

    @GetMapping("/types")
    @ApiOperation("获取所有的对象类型")
    @RequiredUserLevel(UserLevel.User)
    public ResData<List<ObjType>> getObjTypes() {
        return ResData.success(Arrays.asList(ObjType.values()));
    }
}
